using System;
using System.Collections.Generic;
using System.Text;

namespace Common
{
    /// <summary>
    /// 
    /// </summary>
    public class DbTypeHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataProvider"></param>
        /// <param name="dbType"></param>
        /// <param name="size"></param>
        /// <param name="precision"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        public static string getDbDataTypeName(DataProviderType dataProvider, System.Data.SqlDbType dbType, int size, int precision, int scale)
        {
            string dbTypeStr = "nvarchar(255)";
            switch (dataProvider)
            {
                case DataProviderType.MSSQL:
                    dbTypeStr = DbTypeHelper.getMSSQLDbTypeAsString(dbType, size, precision, scale);
                    break;
                default:
                    // TODO: implement oracle, access data provider
                    throw new NotImplementedException("Data provider " + dataProvider.ToString() + " is not implemented.");
            }

            return dbTypeStr;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataProvider"></param>
        /// <param name="typeString"></param>
        /// <param name="size"></param>
        /// <param name="precision"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        public static string getDbDataTypeName(DataProviderType dataProvider, string typeString, int size, int precision, int scale)
        {
            string dbTypeStr = "nvarchar(255)";
            if(dataProvider!= DataProviderType.MSSQL)
            {
                // TODO: implement provider for Oracle and access
                throw new NotImplementedException("Data type not implemented");
            }
            if(typeString.ToLower()== typeof(System.Data.SqlTypes.SqlBinary).ToString().ToLower())
            {
                    dbTypeStr = "image";
            }
            else if (typeString.ToLower() == typeof(byte[]).ToString().ToLower())
            {
                dbTypeStr = "image";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlBoolean).ToString().ToLower())
            {
                dbTypeStr = "bit";
            }
            else if (typeString.ToLower() == typeof(bool).ToString().ToLower())
            {
                dbTypeStr = "bit";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlByte).ToString().ToLower())
            {
                dbTypeStr = "char (" + size + ")";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlBytes).ToString().ToLower())
            {
                dbTypeStr = "char (" + size + ")";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlChars).ToString().ToLower())
            {
                dbTypeStr = "char (" + size + ")";
            }
            else if (typeString.ToLower() == typeof(char[]).ToString().ToLower())
            {
                dbTypeStr = "char (" + size + ")";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlDateTime).ToString().ToLower())
            {
                dbTypeStr = "datetime";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlDecimal).ToString().ToLower())
            {
                dbTypeStr = "decimal";
            }
            else if (typeString.ToLower() == typeof(decimal).ToString().ToLower())
            {
                dbTypeStr = "decimal";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlDouble).ToString().ToLower())
            {
                dbTypeStr = "double";
            }
            else if (typeString.ToLower() == typeof(double).ToString().ToLower())
            {
                dbTypeStr = "double";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlGuid).ToString().ToLower())
            {
                dbTypeStr = "guid";
            }
            else if (typeString.ToLower() == typeof(Guid).ToString().ToLower())
            {
                dbTypeStr = "guid";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlInt16).ToString().ToLower())
            {
                dbTypeStr = "int";
            }
            else if (typeString.ToLower() == typeof(float).ToString().ToLower())
            {
                dbTypeStr = "float";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlInt32).ToString().ToLower())
            {
                dbTypeStr = "int";
            }
            else if (typeString.ToLower() == typeof(int).ToString().ToLower())
            {
                dbTypeStr = "int";
            }
            else if (typeString.ToLower() == typeof(Int16).ToString().ToLower())
            {
                dbTypeStr = "int";
            }
            else if (typeString.ToLower() == typeof(Int32).ToString().ToLower())
            {
                dbTypeStr = "int";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlInt64).ToString().ToLower())
            {
                dbTypeStr = "bigint";
            }
            else if (typeString.ToLower() == typeof(Int64).ToString().ToLower())
            {
                dbTypeStr = "bigint";
            }
            else if (typeString.ToLower() == typeof(long).ToString().ToLower())
            {
                dbTypeStr = "long";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlMoney).ToString().ToLower())
            {
                dbTypeStr = "money";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlSingle).ToString().ToLower())
            {
                dbTypeStr = "float";
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlString).ToString().ToLower())
            {
                dbTypeStr = "nvarchar (" + size + ")";
            }
            else if (typeString.ToLower() == typeof(string).ToString().ToLower())
            {
                dbTypeStr = "nvarchar (" + size + ")";
            }
            else if (typeString.ToLower() == typeof(char[]).ToString().ToLower())
            {
                dbTypeStr = "nvarchar (" + size + ")";
            }
            else 
            {
                dbTypeStr = "nvarchar (" + size + ")";
            }
            
            return dbTypeStr;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataProvider"></param>
        /// <param name="typeString"></param>
        /// <param name="size"></param>
        /// <param name="precision"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        public static System.Data.SqlDbType GetDbTypeFromTableColumnSchema(DataProviderType dataProvider, string typeString, int size, int precision, int scale)
        {
            System.Data.SqlDbType dbType = System.Data.SqlDbType.VarChar;
            if (dataProvider != DataProviderType.MSSQL)
            {
                // TODO: implement provider for Oracle and access
                throw new NotImplementedException("Data type not implemented");
            }
            if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlBinary).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Image;
            }
            else if (typeString.ToLower() == typeof(byte[]).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Image;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlBoolean).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Bit;
            }
            else if (typeString.ToLower() == typeof(bool).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Bit;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlByte).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Char;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlBytes).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Char;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlChars).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Char;
            }
            else if (typeString.ToLower() == typeof(char[]).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Char;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlDateTime).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.DateTime;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlDecimal).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Decimal;
            }
            else if (typeString.ToLower() == typeof(decimal).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Decimal;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlDouble).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Real;
            }
            else if (typeString.ToLower() == typeof(double).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Real;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlGuid).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.UniqueIdentifier;
            }
            else if (typeString.ToLower() == typeof(Guid).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.UniqueIdentifier;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlInt16).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Int;
            }
            else if (typeString.ToLower() == typeof(float).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Float;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlInt32).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Int;
            }
            else if (typeString.ToLower() == typeof(int).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Int;
            }
            else if (typeString.ToLower() == typeof(Int16).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.SmallInt;
            }
            else if (typeString.ToLower() == typeof(Int32).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Int;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlInt64).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.BigInt;
            }
            else if (typeString.ToLower() == typeof(Int64).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.BigInt;
            }
            else if (typeString.ToLower() == typeof(long).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.BigInt;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlMoney).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Money;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlSingle).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.Float;
            }
            else if (typeString.ToLower() == typeof(System.Data.SqlTypes.SqlString).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.NVarChar;
            }
            else if (typeString.ToLower() == typeof(string).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.NVarChar;
            }
            else if (typeString.ToLower() == typeof(char[]).ToString().ToLower())
            {
                dbType = System.Data.SqlDbType.NVarChar;
            }
            else
            {
                dbType = System.Data.SqlDbType.NVarChar;
            }

            return dbType;
        }
        #region private
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbType"></param>
        /// <param name="size"></param>
        /// <param name="precision"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        private static string getMSSQLDbTypeAsString(System.Data.SqlDbType dbType, int size, int precision, int scale)
        {
            string dbTypeStr = "nvarchar(255)";
            switch (dbType)
            {
                case System.Data.SqlDbType.Bit:
                    dbTypeStr = "bit";
                    break;
                case System.Data.SqlDbType.DateTime:
                    dbTypeStr = "datetime";
                    break;
                case System.Data.SqlDbType.Decimal:
                    dbTypeStr = "decimal";
                    break;
                case System.Data.SqlDbType.Float:
                    dbTypeStr = "float";
                    break;
                case System.Data.SqlDbType.Image:
                    dbTypeStr = "image";
                    break;
                case System.Data.SqlDbType.Int:
                    dbTypeStr = "int";
                    break;
                case System.Data.SqlDbType.Money:
                    dbTypeStr = "money";
                    break;
                case System.Data.SqlDbType.NVarChar:
                    dbTypeStr = "nvarchar(" + size + ")";
                    break;
                case System.Data.SqlDbType.Text:
                    dbTypeStr = "text";
                    break;
                case System.Data.SqlDbType.Timestamp:
                    dbTypeStr = "timestamp";
                    break;
                default:
                    dbTypeStr = "nvarchar(255)";
                    break;
            }
            return dbTypeStr;
        }
        #endregion
    }
}
